import { http } from '@/http/http'

/**
 * 生成UUID
 * @param len 长度，默认32位
 * @param radix 基数，默认16进制
 * @returns UUID字符串
 */
export function createUUID(len = 32, radix = 16): string {
  const chars = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'.split('')
  const uuid = []
  let i
  radix = radix || chars.length

  if (len) {
    // 如果指定uuid长度，只是取随机的字符，0|x为位运算，能去掉x的小数位，返回整数位
    for (i = 0; i < len; i++) uuid[i] = chars[0 | Math.random() * radix]
  }
  else {
    let r
    // 如果没有指定uuid长度，按照rfc4122标准生成uuid
    uuid[8] = uuid[13] = uuid[18] = uuid[23] = '-'
    uuid[14] = '4'

    for (i = 0; i < 36; i++) {
      if (!uuid[i]) {
        r = 0 | Math.random() * 16
        uuid[i] = chars[(i === 19) ? (r & 0x3) | 0x8 : r]
      }
    }
  }
  return uuid.join('')
}

// 上传策略接口
interface UploadPolicy {
  accessid: string
  policy: string
  signature: string
  dir: string
  host: string
  domain: string
  expire: string
}

// API响应接口
interface ApiResponse<T = any> {
  status: number
  message: string
  result: T
  success: boolean
}

/**
 * 使用OSS策略上传头像
 * @param filePath 文件路径
 * @param apiUrl 获取上传策略的API地址
 * @param params 请求参数
 * @returns Promise<string> 返回上传后的URL
 */
export function uploadAvatar(filePath: string, apiUrl = '/app/auth/system/sts/policy', params = {}): Promise<string> {
  return new Promise((resolve, reject) => {
    // 显示加载中
    uni.showLoading({ title: '上传中...' })

    // 1. 检查文件是否存在
    if (!filePath) {
      uni.hideLoading()
      uni.showToast({ title: '请选择图片', icon: 'none' })
      reject(new Error('文件路径为空'))
      return
    }

    // 2. 获取文件信息
    uni.getFileInfo({
      filePath,
      success: async (fileInfo) => {
        try {
          // 检查文件大小
          const maxSize = 10 // 10MB
          const sizeInMB = fileInfo.size / 1024 / 1024
          if (sizeInMB > maxSize) {
            uni.hideLoading()
            uni.showToast({ title: `图片大小不能超过${maxSize}MB`, icon: 'none' })
            reject(new Error(`图片大小超过${maxSize}MB`))
            return
          }

          // 3. 获取上传策略
          const policyRes = await http.get<ApiResponse<UploadPolicy>>(apiUrl, params)

          if (!policyRes || !policyRes.result) {
            uni.hideLoading()
            uni.showToast({ title: '获取上传策略失败', icon: 'none' })
            reject(new Error('获取上传策略失败'))
            return
          }

          // 4. 从策略中获取上传参数
          const result = policyRes.result as UploadPolicy
          const { accessid, policy, signature, dir, host, domain, expire } = result

          console.log(result, 'result')

          // 5. 生成文件名
          const fileExtension = filePath.split('.').pop()?.toLowerCase() || 'jpg'
          const fileName = `${createUUID(32)}.${fileExtension}`

          // 6. 构建表单数据
          const formData = {
            key: `${dir}/${fileName}`,
            OSSAccessKeyId: accessid,
            policy,
            Signature: signature,
            success_action_status: 200,
          }

          // 7. 执行上传
          uni.uploadFile({
            url: domain || host,
            filePath,
            name: 'file',
            formData,
            success: (uploadRes) => {
              uni.hideLoading()

              if (uploadRes.statusCode !== 200) {
                uni.showToast({ title: '上传失败', icon: 'none' })
                reject(new Error(`上传失败，状态码: ${uploadRes.statusCode}`))
                return
              }

              // 8. 构建完整的文件URL
              const fileUrl = `${domain || host}/${dir}/${fileName}`

              uni.showToast({ title: '上传成功', icon: 'success' })
              resolve(fileUrl)
            },
            fail: (err) => {
              uni.hideLoading()

              let errorMessage = '上传失败'
              if (err.errMsg) {
                if (err.errMsg.includes('ECONNRESET')) {
                  errorMessage = '网络连接重置，请检查网络'
                }
                else if (err.errMsg.includes('timeout')) {
                  errorMessage = '上传超时，请重试'
                }
                else {
                  errorMessage = err.errMsg
                }
              }

              uni.showToast({ title: errorMessage, icon: 'none' })
              reject(err)
            },
          })
        }
        catch (error) {
          uni.hideLoading()
          uni.showToast({ title: '上传过程出错', icon: 'none' })
          reject(error)
        }
      },
      fail: (err) => {
        uni.hideLoading()
        uni.showToast({ title: '获取文件信息失败', icon: 'none' })
        reject(err)
      },
    })
  })
}

/**
 * 选择并上传头像
 * @param apiUrl 获取上传策略的API地址
 * @param params 请求参数
 * @returns Promise<string> 返回上传后的URL
 */
export function chooseAndUploadAvatar(apiUrl = '/app/auth/system/sts/policy', params = {}): Promise<string> {
  return new Promise((resolve, reject) => {
    uni.chooseImage({
      count: 1, // 头像只需要一张图片
      sizeType: ['original', 'compressed'], // 原图和压缩图都可以
      sourceType: ['album', 'camera'], // 支持相册和相机
      success: async (res) => {
        try {
          const tempFilePath = res.tempFilePaths[0]
          const imageUrl = await uploadAvatar(tempFilePath, apiUrl, params)
          resolve(imageUrl)
        }
        catch (error) {
          reject(error)
        }
      },
      fail: (err) => {
        // 用户取消选择不显示错误提示
        if (!err.errMsg.includes('cancel')) {
          uni.showToast({ title: '选择图片失败', icon: 'none' })
        }
        reject(err)
      },
    })
  })
}

/**
 * 使用示例:
 *
 * import { chooseAndUploadAvatar } from '@/utils/uploadImage'
 *
 * // 基本使用
 * const handleUpload = async () => {
 *   try {
 *     const imageUrl = await chooseAndUploadAvatar('/app/auth/system/sts/policy')
 *     console.log('上传成功，头像地址:', imageUrl)
 *     // 更新表单数据
 *     form.headimgurl = imageUrl
 *   } catch (error) {
 *     console.error('上传失败:', error)
 *   }
 * }
 */
function uploadRequest(file, params) {
  if (!file) {
    return false
    // .toLowerCase()
  }
  else if (!/\.(jpg|jpeg|png|gif)$/.test(file.name)) {
    uni.showToast({
      title: '上传格式不正确，支持上传文件格式：jpg、jpeg、png、gif',
      duration: 2000,
      icon: 'none',
    })
    return false
  }
  let lt2M = file.size / 1024 / 1024 < 10
  if (!lt2M) {
    this.$message.error()
    uni.showToast({
      title: `上传图片大小不能超过 ${10}MB!`,
      duration: 2000,
      icon: 'none',
    })
    return false
  }
  let pos = file.name.lastIndexOf('.');
  let suffix = '.png'
  // console.log('suffix = .png;')
  if (pos !== -1) {
    suffix = file.name.substring(pos)
  }
  // console.log('if(pos !== -1)')
  let fname = createUUID(32) + suffix
  console.log(fname, 'fname’')
  let config = params.result

  let formData = {
    key: `${config.dir}/${!fname ? file.name : fname}`,
    OSSAccessKeyId: config.accessid,
    policy: config.policy,
    Signature: config.signature,
    success_action_status: 200,
    // "file": file
  }
  console.log(file.path, 'filePath', formData, 'formData', fname, 'fname', file, 'file')
  uni.uploadFile({
    url: config.domain,
    filePath: file.path,
    name: 'file',
    formData,
    success: (uploadFileRes) => {
      const successPath = `${config.domain}/${formData.key}`
      console.log('成功', uploadFileRes, successPath)
      if (props.limit == 1) {
        imageValue.splice(0, 1, { url: file.path, name: successPath })
      }
      else {
        imageValue.push({ url: file.path, name: successPath })
      }
      console.log(uploadFileRes.data, imageValue, 'success')
      let str = imageValue.map(item => item.name).join(',')
      emit('inputValue', str)
    },
  })
}
